from typing import Any
from fastapi import APIRouter, Depends, HTTPException, UploadFile, File
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select

from ...core.auth import get_current_user, get_password_hash, verify_password
from ...database import get_db
from ...models.user import User, UserPreference
from ...schemas.user import (
    UserUpdate,
    UserPasswordChange,
    UserPreferenceUpdate,
    UserProfileResponse,
    UserResponse,
    User as UserSchema,
    UserProfile
)
from ...services.oss_service import get_oss_service, OSSService
import logging

logger = logging.getLogger(__name__)

router = APIRouter()


@router.get("/profile", response_model=UserProfileResponse)
async def get_user_profile(
    current_user: UserSchema = Depends(get_current_user),
    db: AsyncSession = Depends(get_db)
) -> Any:
    """获取用户个人资料"""
    try:
        # 获取用户完整信息，包括偏好设置
        user_query = select(User).where(User.id == current_user.id)
        result = await db.execute(user_query)
        user = result.scalar_one_or_none()
        if not user:
            raise HTTPException(status_code=404, detail="用户不存在")
        
        # 获取用户偏好设置
        preference_query = select(UserPreference).where(
            UserPreference.user_id == user.id
        )
        pref_result = await db.execute(preference_query)
        preference = pref_result.scalar_one_or_none()
        
        # 构建用户资料对象
        user_profile = UserProfile(
            id=user.id,
            username=user.username,
            email=user.email,
            nickname=user.nickname,
            bio=user.bio,
            phone=user.phone,
            gender=user.gender,
            birthday=user.birthday,
            location=user.location,
            avatar=user.avatar,
            last_login_at=user.last_login_at,
            login_count=user.login_count,
            created_at=user.created_at,
            updated_at=user.updated_at,
            is_active=user.is_active,
            is_verified=user.is_verified,
            preferences=preference
        )
        
        return UserProfileResponse(
            code=200,
            message="获取用户资料成功",
            data=user_profile
        )
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"获取用户资料失败: {e}")
        raise HTTPException(status_code=500, detail="获取用户资料失败")


@router.put("/profile", response_model=UserResponse)
async def update_user_profile(
    user_update: UserUpdate,
    current_user: UserSchema = Depends(get_current_user),
    db: AsyncSession = Depends(get_db)
) -> Any:
    """更新用户个人资料"""
    try:
        # 获取当前用户
        user_query = select(User).where(User.id == current_user.id)
        result = await db.execute(user_query)
        user = result.scalar_one_or_none()
        if not user:
            raise HTTPException(status_code=404, detail="用户不存在")
        
        # 更新用户信息
        update_data = user_update.dict(exclude_unset=True)
        for field, value in update_data.items():
            if hasattr(user, field):
                setattr(user, field, value)
        
        await db.commit()
        await db.refresh(user)
        
        return UserResponse(
            code=200,
            message="用户资料更新成功",
            data=UserSchema.from_orm(user)
        )
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"更新用户资料失败: {e}")
        await db.rollback()
        raise HTTPException(status_code=500, detail="更新用户资料失败")


@router.post("/change-password")
async def change_password(
    password_data: UserPasswordChange,
    current_user: UserSchema = Depends(get_current_user),
    db: AsyncSession = Depends(get_db)
) -> Any:
    """修改密码"""
    try:
        # 获取当前用户
        user_query = select(User).where(User.id == current_user.id)
        result = await db.execute(user_query)
        user = result.scalar_one_or_none()
        if not user:
            raise HTTPException(status_code=404, detail="用户不存在")
        
        # 验证旧密码
        if not verify_password(password_data.old_password, user.password_hash):
            raise HTTPException(status_code=400, detail="原密码错误")
        
        # 更新密码
        user.password_hash = get_password_hash(password_data.new_password)
        await db.commit()
        
        return {
            "code": 200,
            "message": "密码修改成功",
            "data": None
        }
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"修改密码失败: {e}")
        await db.rollback()
        raise HTTPException(status_code=500, detail="修改密码失败")


@router.post("/upload-avatar")
async def upload_avatar(
    file: UploadFile = File(...),
    current_user: UserSchema = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
    oss_service: OSSService = Depends(get_oss_service)
) -> Any:
    """上传头像"""
    try:
        # 验证文件类型
        if not file.content_type or not file.content_type.startswith('image/'):
            raise HTTPException(
                status_code=400,
                detail="只支持图片文件"
            )
        
        # 上传文件到OSS，返回 (file_key, file_url)
        file_key, file_url = await oss_service.upload_file(file, "avatars")
        
        # 更新用户头像
        user_query = select(User).where(User.id == current_user.id)
        result = await db.execute(user_query)
        user = result.scalar_one_or_none()
        if not user:
            raise HTTPException(status_code=404, detail="用户不存在")
        
        # 如果用户之前有头像，删除旧的头像文件
        if user.avatar and user.avatar != file_url:
            try:
                # 从URL中提取文件key
                if user.avatar.startswith('http'):
                    # 从URL中提取文件路径
                    url_parts = user.avatar.split('/')
                    old_file_key = f"{url_parts[-2]}/{url_parts[-1]}"
                    oss_service.delete_file(old_file_key)
            except Exception as e:
                logger.warning(f"删除旧头像失败: {e}")
        
        user.avatar = file_url
        await db.commit()
        
        return {
            "code": 200,
            "message": "头像上传成功",
            "data": {
                "avatar_url": file_url,
                "file_key": file_key
            }
        }
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"头像上传失败: {e}")
        await db.rollback()
        raise HTTPException(status_code=500, detail="头像上传失败")


@router.get("/preferences", response_model=dict)
async def get_user_preferences(
    current_user: UserSchema = Depends(get_current_user),
    db: AsyncSession = Depends(get_db)
) -> Any:
    """获取用户偏好设置"""
    try:
        preference_query = select(UserPreference).where(
            UserPreference.user_id == current_user.id
        )
        result = await db.execute(preference_query)
        preference = result.scalar_one_or_none()
        
        if not preference:
            # 如果没有偏好设置，创建默认设置
            preference = UserPreference(
                user_id=current_user.id,
                language='zh-CN',
                theme='light',
                voice_enabled=True,
                voice_speed=1.0,
                auto_play_voice=True,
                notification_enabled=True,
                favorite_novels=[],
                favorite_characters=[],
                privacy_settings={}
            )
            db.add(preference)
            await db.commit()
            await db.refresh(preference)
        
        # 构建偏好设置数据
        preference_data = {
            "id": preference.id,
            "user_id": preference.user_id,
            "favorite_avatar_id": preference.favorite_avatar_id,
            "favorite_novels": preference.favorite_novels or [],
            "favorite_characters": preference.favorite_characters or [],
            "language": preference.language,
            "theme": preference.theme,
            "voice_enabled": preference.voice_enabled,
            "voice_speed": float(preference.voice_speed),
            "auto_play_voice": preference.auto_play_voice,
            "notification_enabled": preference.notification_enabled,
            "privacy_settings": preference.privacy_settings or {},
            "created_at": preference.created_at,
            "updated_at": preference.updated_at
        }
        
        return {
            "code": 200,
            "message": "获取用户偏好成功",
            "data": preference_data
        }
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"获取用户偏好失败: {e}")
        raise HTTPException(status_code=500, detail="获取用户偏好失败")


@router.put("/preferences")
async def update_user_preferences(
    preference_update: UserPreferenceUpdate,
    current_user: UserSchema = Depends(get_current_user),
    db: AsyncSession = Depends(get_db)
) -> Any:
    """更新用户偏好设置"""
    try:
        preference_query = select(UserPreference).where(
            UserPreference.user_id == current_user.id
        )
        result = await db.execute(preference_query)
        preference = result.scalar_one_or_none()
        
        if not preference:
            # 如果没有偏好设置，创建新的
            preference = UserPreference(user_id=current_user.id)
            db.add(preference)
        
        # 更新偏好设置
        update_data = preference_update.dict(exclude_unset=True)
        for field, value in update_data.items():
            if hasattr(preference, field):
                setattr(preference, field, value)
        
        await db.commit()
        await db.refresh(preference)
        
        return {
            "code": 200,
            "message": "用户偏好更新成功",
            "data": None
        }
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"更新用户偏好失败: {e}")
        await db.rollback()
        raise HTTPException(status_code=500, detail="更新用户偏好失败")


@router.post("/favorites/novels/{novel_id}")
async def add_favorite_novel(
    novel_id: int,
    current_user: UserSchema = Depends(get_current_user),
    db: AsyncSession = Depends(get_db)
) -> Any:
    """添加收藏小说"""
    try:
        preference_query = select(UserPreference).where(
            UserPreference.user_id == current_user.id
        )
        result = await db.execute(preference_query)
        preference = result.scalar_one_or_none()
        
        if not preference:
            preference = UserPreference(user_id=current_user.id)
            db.add(preference)
            await db.flush()
        
        favorite_novels = preference.favorite_novels or []
        if novel_id not in favorite_novels:
            favorite_novels.append(novel_id)
            preference.favorite_novels = favorite_novels
            await db.commit()
        
        return {
            "code": 200,
            "message": "添加收藏成功",
            "data": None
        }
        
    except Exception as e:
        logger.error(f"添加收藏小说失败: {e}")
        await db.rollback()
        raise HTTPException(status_code=500, detail="添加收藏失败")


@router.delete("/favorites/novels/{novel_id}")
async def remove_favorite_novel(
    novel_id: int,
    current_user: UserSchema = Depends(get_current_user),
    db: AsyncSession = Depends(get_db)
) -> Any:
    """移除收藏小说"""
    try:
        preference_query = select(UserPreference).where(
            UserPreference.user_id == current_user.id
        )
        result = await db.execute(preference_query)
        preference = result.scalar_one_or_none()
        
        if preference and preference.favorite_novels:
            favorite_novels = preference.favorite_novels[:]
            if novel_id in favorite_novels:
                favorite_novels.remove(novel_id)
                preference.favorite_novels = favorite_novels
                await db.commit()
        
        return {
            "code": 200,
            "message": "移除收藏成功",
            "data": None
        }
        
    except Exception as e:
        logger.error(f"移除收藏小说失败: {e}")
        await db.rollback()
        raise HTTPException(status_code=500, detail="移除收藏失败")


@router.post("/favorites/characters/{character_id}")
async def add_favorite_character(
    character_id: int,
    current_user: UserSchema = Depends(get_current_user),
    db: AsyncSession = Depends(get_db)
) -> Any:
    """添加收藏角色"""
    try:
        preference_query = select(UserPreference).where(
            UserPreference.user_id == current_user.id
        )
        result = await db.execute(preference_query)
        preference = result.scalar_one_or_none()
        
        if not preference:
            preference = UserPreference(user_id=current_user.id)
            db.add(preference)
            await db.flush()
        
        favorite_characters = preference.favorite_characters or []
        if character_id not in favorite_characters:
            favorite_characters.append(character_id)
            preference.favorite_characters = favorite_characters
            await db.commit()
        
        return {
            "code": 200,
            "message": "添加收藏成功",
            "data": None
        }
        
    except Exception as e:
        logger.error(f"添加收藏角色失败: {e}")
        await db.rollback()
        raise HTTPException(status_code=500, detail="添加收藏失败")


@router.delete("/favorites/characters/{character_id}")
async def remove_favorite_character(
    character_id: int,
    current_user: UserSchema = Depends(get_current_user),
    db: AsyncSession = Depends(get_db)
) -> Any:
    """移除收藏角色"""
    try:
        preference_query = select(UserPreference).where(
            UserPreference.user_id == current_user.id
        )
        result = await db.execute(preference_query)
        preference = result.scalar_one_or_none()
        
        if preference and preference.favorite_characters:
            favorite_characters = preference.favorite_characters[:]
            if character_id in favorite_characters:
                favorite_characters.remove(character_id)
                preference.favorite_characters = favorite_characters
                await db.commit()
        
        return {
            "code": 200,
            "message": "移除收藏成功",
            "data": None
        }
        
    except Exception as e:
        logger.error(f"移除收藏角色失败: {e}")
        await db.rollback()
        raise HTTPException(status_code=500, detail="移除收藏失败")


@router.get("/stats")
async def get_user_stats(
    current_user: UserSchema = Depends(get_current_user),
    db: AsyncSession = Depends(get_db)
) -> Any:
    """获取用户统计信息"""
    try:
        user_query = select(User).where(User.id == current_user.id)
        result = await db.execute(user_query)
        user = result.scalar_one_or_none()
        if not user:
            raise HTTPException(status_code=404, detail="用户不存在")
        
        preference_query = select(UserPreference).where(
            UserPreference.user_id == current_user.id
        )
        pref_result = await db.execute(preference_query)
        preference = pref_result.scalar_one_or_none()
        
        stats_data = {
            "login_count": user.login_count,
            "last_login_at": user.last_login_at,
            "created_at": user.created_at,
            "favorite_novels_count": len(preference.favorite_novels or []) if preference else 0,
            "favorite_characters_count": len(preference.favorite_characters or []) if preference else 0,
            "is_verified": user.is_verified
        }
        
        return {
            "code": 200,
            "message": "获取用户统计成功",
            "data": stats_data
        }
        
    except Exception as e:
        logger.error(f"获取用户统计失败: {e}")
        raise HTTPException(status_code=500, detail="获取用户统计失败") 